package com.urbanski.util.io;

import java.io.File;
import java.io.FileFilter;
import java.util.Arrays;

/**
 * A FileFilter implementation that accepts files based on the file extension. The file extension is
 * defined to be the value after the last period in the file's name, not counting the period itself.
 * Note that this means that any file extension filter that contains a period will never match a
 * file.
 * 
 * Filenames that do not contain a period by definition do not have an extension, and can be matched
 * by providing this class a zero-length list of extensions (via the default constructor or by
 * passing an empty array to the var-args constructor).
 * 
 * Passing a file extension of "" (empty string) to this class will not match a file with no
 * extension; rather, it will match a file ending with a period.
 * 
 * @author murbanski004
 * 
 */
public class FileExtensionFilter implements FileFilter
{
	private String[] extensions;

	/**
	 * Constructs a new FileExtensionFilter that matches files with no extension
	 */
	public FileExtensionFilter()
	{
		extensions = new String[0];
	}

	/**
	 * Constructs a new FileExtensionFilter that matches the specified extension
	 * 
	 * @param extension the file extension to match (not counting the period)
	 */
	public FileExtensionFilter(String extension)
	{
		extensions = new String[] { extension };
	}

	/**
	 * Constructs a new FileExtensionFilter that matches the specified list of extensions. If an
	 * empty array is passed, then functions the same as if the default constructor were used.
	 * 
	 * @param extensions the extensions to match
	 */
	public FileExtensionFilter(String... extensions)
	{
		this.extensions = new String[extensions.length];
		System.arraycopy(extensions, 0, this.extensions, 0, extensions.length);
		Arrays.sort(extensions);
	}

	@Override
	public boolean accept(File file)
	{
		String filename = file.getName();
		int extIndex = filename.lastIndexOf('.');
		
		return extensions.length == 0 ? extIndex == -1 : (extIndex == -1 ? false : Arrays.binarySearch(extensions, filename.substring(extIndex + 1)) >= 0);
	}
}
